<template>
  <div class="container">
    <div class="tools">
      <slot name="tool"/>
    </div>
    <div class="map" id="amap">

    </div>
    <el-dialog class="areaDialog el_nohead_nobody" :visible.sync="showAreaModal" :show-close="false" v-if="showAreaModal"  append-to-body
               :before-close="handleCancelSaveArea">
      <AreaForm :destroy-on-close="true" :dataSource="areaModel" @save="handleSaveArea" @delete="handleRemoveArea"/>
    </el-dialog>

    <el-dialog custom-class="form-dialog" title="箭头" :visible.sync="showArrowModal" width="400px" :fullscreen="false"
               :modal-append-to-body="false" :append-to-body="false" :modal="false"
               :before-close="handleCancelSaveArrow">
      <ArrowForm :destroy-on-close="true" :dataSource="arrowModel" @save="handleSaveArrow" @delete="handleRemoveArrow"/>
    </el-dialog>
    <el-dialog custom-class="form-dialog" title="标点" :visible.sync="showMarkModal" width="400px" :fullscreen="false"
               :modal-append-to-body="false" :append-to-body="false" :modal="false"
               :before-close="handleCancelSaveMark">
      <MarkForm :destroy-on-close="true" :dataSource="markModel" @save="handleSaveMark" @delete="handleRemoveMark"/>
    </el-dialog>
  </div>
</template>

<script>
import * as API from '@/api/area';
import AreaForm from './AreaForm.vue';
import ArrowForm from './ArrowForm.vue';
import MarkForm from './MarkForm.vue';
// import DialogList from './DialogList.vue';
import {getMarkIconUrl} from '@/utils/utils';

export default {
  name: 'AMap',
  props: {
    positions: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      position: {
        x: 0,
        y: 0,
      },
      areaList: [],
      editMode: 'new',
      showAreaModal: true,
      showArrowModal: false,
      showMarkModal: false,
      areaModel: {
        id: '',
        areaName: '',
        remake: '',
        color: '#ff0000',
      },
      arrowModel: {
        id: '',
        areaName: '',
        remake: '',
        color: '#ff0000',
        lineWidth: 2,
      },
      markModel: {
        id: '',
        areaName: '',
        remake: '',
        symbol: 'default',
        symbolSize: 20,
        whetherName: 1,
      },
    };
  },
  methods: {
    async fetchAllListData() {
      this.$tmap.clearOverLays();
      const res = await API.getAreaList(10000, 1);
      this.areaList = res.data.records || [];
      this.renderList();
    },
    handleCancelSaveArea() {
      this.closeAreaModal();
      if (this.editMode === 'new') {
        this.handleRemoveArea();
      }
    },
    handleCancelSaveArrow() {
      this.closeArrowModal();
      if (this.editMode === 'new') {
        this.handleRemoveArrow();
      }
    },
    handleCancelSaveMark() {
      this.closeMarkModal();
      if (this.editMode === 'new') {
        this.handleRemoveMark();
      }
    },
    closeAreaModal() {
      this.showAreaModal = false;
      this.areaModel = {
        areaName: '',
        remake: '',
        color: '#00ff00',
      };
    },
    closeArrowModal() {
      this.showArrowModal = false;
      this.arrowModel = {
        areaName: '',
        remake: '',
        line: '#00ff00',
        color: '#00ff00',
        lineWidth: 2,
      };
    },
    closeMarkModal() {
      this.showMarkModal = false;
      this.markModel = {
        areaName: '',
        remake: '',
        symbol: 'default',
        color: '#ff0000',
        symbolSize: 20,
        whetherName: 1,
      };
    },
    renderList() {
      this.areaList.forEach((item) => {
        if (+item.type === 1) {
          this.addMark(item);
        }
        if (+item.type === 2) {
          this.addArea(item);
        }
        if (+item.type === 3) {
          this.addArrow(item);
        }
      })
    },
    addMark(item) {
      const data = JSON.parse(item.lnglat || '{}');
      if (!data.lng || !data.lat) {
        return;
      }
      const iconType = item.symbol || 'default';
      const mark = new T.Marker(new T.LngLat(data.lng, data.lat), {
        icon: new T.Icon({
          iconUrl: getMarkIconUrl(iconType),
          iconSize: item.symbolSize ? +item.symbolSize : 20,
        }),
        title: item.areaName,
        extra: item,
      });
      mark.addEventListener('contextmenu', ({target}) => {
        const data = target.options.extra || {};
        this.editMode = 'edit';
        this.$mark = target;
        this.$lnglat = JSON.parse(data.lnglat);
        this.markModel = {
          id: data.id,
          areaName: data.areaName,
          remake: data.remake,
          symbol: data.symbol || 'default',
          symbolSize: data.symbolSize || 20,
          whetherName: data.whetherName ? +data.whetherName : 1,
        };
        this.openMarkForm();
      });
      this.$tmap.addOverLay(mark);
    },
    addArea(item) {
      const data = JSON.parse(item.bounds || '{}');
      const leftLngLat = data.left;
      const rightLngLat = data.right;
      if (!leftLngLat || !rightLngLat) {
        return;
      }
      const bounds = new T.LngLatBounds(new T.LngLat(leftLngLat.lng, leftLngLat.lat), new T.LngLat(rightLngLat.lng, rightLngLat.lat));
      const rect = new T.Rectangle(bounds, {
        color: item.color || '#ff0000',
        opacity: 0.5,
        fillColor: item.color || '#ff0000',
        extra: item,
      });
      rect.addEventListener('contextmenu', ({target}) => {
        this.$area = target;

        const data = target.options.extra || {};
        this.areaModel = {
          id: data.id,
          areaName: data.areaName,
          remake: data.remake,
          color: data.color,
        };
        this.editMode = 'edit';
        const bounds = JSON.parse(data.bounds || '{}');
        this.$bounds = {
          left: bounds.left,
          right: bounds.right,
        };
        this.openAreaForm();
      });
      this.$tmap.addOverLay(rect);
    },
    addArrow(item) {
      const paths = JSON.parse(item.paths || '[]');
      if (!paths.length) {
        return;
      }
      const points = paths.map((path) => {
        return new T.LngLat(path[1], path[0]);
      });
      const polylineArrow = new T.PolylineArrow(points, {
        color: item.color || '#ff0000',
        weight: item.lineWidth ? +item.lineWidth : 3,
        lineStyle: 'solid',
        extra: item,
      });
      polylineArrow.addEventListener('contextmenu', ({target}) => {
        this.$currentLayer = target;
        this.editMode = 'edit';
        const data = target.options.extra || {};
        this.arrowModel = {
          id: data.id,
          areaName: data.areaName,
          remake: data.remake,
          color: data.color,
          lineWidth: data.lineWidth,
        };
        const paths = JSON.parse(data.paths || '[]');
        this.$paths = paths;
        this.openArrowForm();
      });
      this.$tmap.addOverLay(polylineArrow);
    },
    async handleSaveArea(values) {
      if (this.editMode === 'edit') {
        values.id = this.areaModel.id;
      }
      const res = await API.saveArea({
        ...values,
        bounds: JSON.stringify(this.$bounds),
      });
      if (res.code === 200) {
        this.$message.success('保存成功');
        this.closeAreaModal();
        this.fetchAllListData();
      } else {
        this.$message.warning(res.msg);
      }
    },
    async handleRemoveArea() {
      if (this.editMode === 'new') {
        this.$bounds = {};
        this.closeAreaModal();
        this.$tmap.removeOverLay(this.$area);
      } else {
        const isSuccess = await this.removeData(this.areaModel.id);
        if (isSuccess) {
          this.$bounds = {};
          this.closeAreaModal();
          this.$tmap.removeOverLay(this.$area);
        }
      }
    },
    async removeData(id) {
      const res = await API.deleteArea(id);
      if (res.code === 200) {
        this.$message.success('删除成功');
      } else {
        this.$message.error(res.msg || '删除失败');
      }
      return res.code === 0;
    },
    drawArea() {
      if (this.$handler) {
        this.$handler.close()
      }
      this.$handler = new T.RectangleTool(this.$tmap, {
        follow: true
      });
      this.$handler.addEventListener('draw', ({currentBounds, currentRectangle}) => {
        // console.log('currentBounds =', currentBounds);
        this.openAreaForm();
        this.editMode = 'new';
        this.$area = currentRectangle;
        this.$bounds = {
          left: currentBounds.kq,
          right: currentBounds.Lq,
        };
      });
      this.$handler.open();
    },
    openAreaForm() {
      this.showAreaModal = true;
    },
    openArrowForm() {
      this.showArrowModal = true;
    },
    drawArrow() {
      if (this.$handler) {
        this.$handler.close();
      }
      this.$handler = new T.PolylineArrowTool(this.$tmap, {fill: true});
      this.$handler.addEventListener('dbclick', ({currentLnglats, currentLayer}) => {
        this.openArrowForm();
        // console.log('currentLnglats =', currentLnglats);
        // console.log('target =', target);
        // console.log('currentLayer =', currentLayer);
        this.$paths = currentLnglats;
        this.$currentLayer = currentLayer;
      });
      this.$handler.open();
    },
    async handleSaveArrow(values) {
      if (this.editMode === 'edit') {
        values.id = this.arrowModel.id;
      }
      const res = await API.saveArea({
        ...values,
        paths: JSON.stringify(this.$paths),
      });
      if (res.code === 200) {
        this.$message.success('保存成功');
        this.closeArrowModal();
        this.fetchAllListData();
      } else {
        this.$message.warning(res.msg || '保存失败');
      }
    },
    async handleRemoveArrow() {
      this.$paths = {};
      if (this.editMode === 'new') {
        this.closeArrowModal();
        this.$tmap.clearOverLays();
        this.renderList();
      } else {
        const isSuccess = await this.removeData(this.arrowModel.id);
        if (isSuccess) {
          this.closeArrowModal();
          this.$tmap.clearOverLays();
          this.renderList();
        }
      }

      // 这里直接用removeOverLay 删不掉箭头，
      // 暂时用清空地图所有的覆盖物方法，再重新绘制所有的标记物。。。
      // this.$tmap.removeOverLay(this.$currentLayer);
    },
    openMarkForm() {
      this.showMarkModal = true;
    },
    drawMark() {
      if (this.$handler) {
        this.$handler.close();
      }
      this.$handler = new T.MarkTool(this.$tmap, {
        follow: true,
        icon: new T.Icon({
          iconUrl: getMarkIconUrl('default'),
          iconSize: 20,
        })
      });
      this.$handler.addEventListener('mouseup', ({currentLnglat, currentMarker}) => {
        this.$mark = currentMarker;
        this.$lnglat = currentLnglat;
        this.openMarkForm();
      })
      this.$handler.open();
    },
    async handleSaveMark(values) {
      if (this.editMode === 'edit') {
        values.id = this.markModel.id;
      }
      const res = await API.saveArea({
        ...values,
        lnglat: JSON.stringify(this.$lnglat),
      });
      if (res.code === 200) {
        this.$message.success('保存成功');
        this.closeMarkModal();
        this.fetchAllListData();
      } else {
        this.$message.warning(res.msg);
      }
    },
    async handleRemoveMark() {
      this.$lnglat = {};
      if (this.editMode === 'new') {
        this.closeMarkModal();
        this.$tmap.removeOverLay(this.$mark);
      } else {
        const isSuccess = await this.removeData(this.markModel.id);
        if (isSuccess) {
          this.closeMarkModal();
          this.$tmap.removeOverLay(this.$mark);
        }
      }
    },
    clearAll() {
      this.$confirm('确认清空所有标记数据吗？', '提示')
          .then(async () => {
            API.clearAll()
                .then((res) => {
                  if (res.code === 200) {
                    this.$message.success('清空成功');
                    this.$tmap.clearOverLays();
                  } else {
                    this.$message.error(res.msg);
                  }
                })
          });
    },
    initData() {
      this.fetchAllListData();
      this.initEvents();
    },
    initEvents() {
      // this.$mouseTool = new AMap.MouseTool(this.$map);
      this.$event.on('draw::area', () => {
        // this.drawArea();
      });
      this.$event.on('draw::mark', () => {
        // this.drawMark();
      });
      this.$event.on('draw::arrow', () => {
        // this.drawArrow();
      });
      this.$event.on('draw::clear', () => {
        // this.clearAll();
      });
    },
    initMap() {
      // eslint-disable-next-line no-undef
      this.$tmap = new T.Map('amap');
      // 地图初始化坐标中心点应该使用3维地图传过来的坐标进行初始化...
      this.$tmap.centerAndZoom(new T.LngLat(116.40769, 39.89945), 12);
      this.initData();
      // this.$map = new AMap.Map('amap', {
      //   viewMode: '2D',
      //   zoom: 10,
      // });
      // this.$map.on('complete', () => {
      //   this.initData();
      // })
    },
    loadMap() {
      this.initMap();
    },
  },
  mounted() {
    // window._AMapSecurityConfig = {
    //   securityJsCode:'71a9958311f962fbe629f7eb0cb1b302',
    // }
    this.initEvents();
  },
  components: {
    AreaForm,
    ArrowForm,
    MarkForm,
  },
}
</script>

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
  position: relative;
}

.map {
  width: 100%;
  height: 100%;
}

.tool {
  position: absolute;
  left: 20px;
  top: 20px;
}
</style>
<style lang="scss">

@import "@/styles/dialog.scss";

.areaDialog{
  .el-dialog {
    width: 411px;
    height: 250px;
    background-color: transparent;
    border: 0px solid transparent;
  }
}

.dialog-list {
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  // width: 400px;
  // background: #1A2A47;
  position: fixed;
  z-index: 4;
}

.form-dialog {
  background: #1A2A47;

  .el-dialog__title {
    color: #fff;
  }

  .el-dialog__headerbtn .el-dialog__close {
    color: #fff;
    font-size: 18px;
  }

  .el-form-item__label {
    color: rgba(255, 255, 255, 0.6);
  }

  .el-input__inner {
    background: transparent;
    color: rgba(255, 255, 255, 0.6);
    border: 1px solid rgba(98, 183, 255, 0.3);
  }

  .el-input.is-active, .el-input__inner:focus {
    border-color: rgba(21, 154, 255, 0.5);
  }
}
</style>